1. Java IO

2. 概念

Java IO 是一套Java用来读写数据(输入和输出)的API。大部分程序都要处理一些输入,并由输入产生一些输出。Java为此提供了java.io包

2.1. 磁盘操作:File

File 表示文件目录,但不表示文件内容,以下代码递归的展示一个目录下的所有文件

    public static void main(String[] args) {
        listAllFiles(new File("/Users/gaohueric/Documents/SublimeWorkStation"));
    }

    public static void listAllFiles(File dir) {
        if (dir == null || !dir.exists()) {
            return;
        }
        if (dir.isFile()) {
            System.out.println(dir.getName());
            return;
        }
        for (File file : dir.listFiles()) {
            listAllFiles(file);
        }
    }

3. 字节操作

3.1. 文件拷贝的几种方式

实现文件复制,读取一个文件写入另外一个文件,将字符转换为字节,再写入文件。

    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = new FileInputStream("/Users/gaohueric/Documents/known_hosts");
        FileOutputStream fileOutputStream = new FileOutputStream("/Users/gaohueric/Documents/new_known_hosts");

        byte[] buffer = new byte[20*1024];
        int cnt;
        while((cnt = fileInputStream.read(buffer,0,buffer.length)) != -1){
            fileOutputStream.write(buffer,0,cnt);
        }
        fileInputStream.close();
        fileOutputStream.close();
    }

结果输出到文件

    public static void main(String[] args) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream("/Users/gaohueric/Documents/test.txt");
        for(int i=0;i<100;i++){
            String message = "test\r\n";
            fileOutputStream.write(message.getBytes());
        }
    }

通过普通的缓冲输入输出流拷贝文件

    public static void main(String[] args) throws IOException {
        InputStream in = null;
        OutputStream out = null;
        try {
            in = new BufferedInputStream(new FileInputStream("/Users/gaohueric/Documents/known_hosts"));
            out = new BufferedOutputStream(new FileOutputStream("/Users/gaohueric/Documents/new_test.txt"));
            byte[] buffer = new byte[2048];
            int i;
            while ((i = in.read(buffer)) != -1) {
                out.write(buffer, 0, i);
            }

        } catch (Exception e) {
            System.out.println(1);
        } finally {
            in.close();
            out.close();
        }
    }

通过文件管道的方式复制文件 基于NIO的方式

public static void main(String[] args) throws IOException {
    FileChannel in = new FileInputStream("/Users/gaohueric/Documents/known_hosts").getChannel();
    FileChannel out = new FileOutputStream("/Users/gaohueric/Documents/new_test.txt").getChannel();
    in.transferTo(0,in.size(),out);
}

通过管道方式复制文件比缓冲流快了三分之一

原因分析:当我们使用输入输出流进行读写时,实际上是进行了多次上下文切换,比如应用读取数据时,先在内核态将数据从磁盘读取到内核缓存,再切换到用户态将数据从内核缓存读取到用户缓存。 通过缓冲流方式会带来一定的上下文切换开销,会降低IO效率。

而基于 NIO transferTo 的实现方式,在 Linux 和 Unix 上,则会使用到零拷贝技术,数据传输并不需要用户态参与,省去了上下文切换的开销和不必要的内存拷贝,进而可能提高应用拷贝性能。注意,transferTo 不仅仅是可以用在文件拷贝中,与其类似的,例如读取磁盘文件,然后进行 Socket 发送,同样可以享受这种机制带来的性能和扩展性提高。

4. 字符操作

String的编码方式:编码与解码

String str1 = "测试";
byte[] bytes = str1.getBytes("UTF-8");
String str2 = new String(bytes, "UTF-8");
System.out.println(str2);

Reader 与 Writer 从文件中读取字节流,转换为字符 输出

  • InputStreamReader 实现从字节流解码成字符流;
  • OutputStreamWriter 实现字符流编码成为字节流。

一下代码实现逐行输出文本文件的内容

    public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader("/Users/gaohueric/Documents/known_hosts");
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        String line;
        while((line = bufferedReader.readLine()) != null){
            System.out.println(line);
        }
        bufferedReader.close();
        fileReader.close();
    }

5. IO模型

Java中IO系统可以分为BIO,NIO,AIO三种IO模型

  • BIO(blocking I/O) 同步阻塞IO BIO是同步阻塞IO,JDK1.4之前只有这一个IO模型,BIO操作的对象是流,一个线程只能处理一个流的IO请求,如果想要同时处理多个流就需要使用多线程
  • NIO(Non-blocking I/O) 同步非阻塞IO,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
  • AIO(NIO.2) (Asynchronous I/O) 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理.
© gaohueric all right reserved,powered by Gitbook文件修订时间: 2021-12-08 23:22:22

results matching ""

    No results matching ""